package com.management.department.teacherinfosystem.Controller;

import com.management.department.teacherinfosystem.Entity.*;
import com.management.department.teacherinfosystem.Repository.*;
import com.management.department.teacherinfosystem.Utils.ExcelExportUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import jakarta.persistence.criteria.Predicate;
import java.util.*;

/**
 * 导出控制器
 */
@RestController
@RequestMapping("/api/export")
@CrossOrigin(origins = "*")
public class ExportController {

    @Autowired
    private TeachingProjectRepository teachingProjectRepository;
    
    @Autowired
    private ResearchProjectRepository researchProjectRepository;
    
    @Autowired
    private AcademicAchievementRepository academicAchievementRepository;
    
    @Autowired
    private AwardRepository awardRepository;
    
    @Autowired
    private ActivityRepository activityRepository;
    
    @Autowired
    private StudentGuidanceRepository studentGuidanceRepository;
    
    @Autowired
    private TextbookRepository textbookRepository;
    
    @Autowired
    private CourseHoursRepository courseHoursRepository;
    
    @Autowired
    private VolunteerServiceRepository volunteerServiceRepository;
    
    @Autowired
    private PartyActivityRepository partyActivityRepository;
    
    @Autowired
    private AcademicPositionRepository academicPositionRepository;
    
    @Autowired
    private TalentHonorRepository talentHonorRepository;

    /**
     * 导出教学项目
     */
    @GetMapping("/teaching-projects")
    public ResponseEntity<byte[]> exportTeachingProjects(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "level", required = false) String level,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<TeachingProject> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + search + "%"));
            }
            
            if (status != null && !status.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("projectType"), type));
            }
            
            if (level != null && !level.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("level"), level));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<TeachingProject> projects = teachingProjectRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("name", "项目名称");
        headers.put("projectType", "项目类型");
        headers.put("level", "项目级别");
        headers.put("status", "项目状态");
        headers.put("startDate", "开始日期");
        headers.put("endDate", "结束日期");
        headers.put("user.name", "负责人");
        
        return ExcelExportUtil.exportToExcel(projects, headers, "教学项目列表");
    }

    /**
     * 导出科研项目
     */
    @GetMapping("/research-projects")
    public ResponseEntity<byte[]> exportResearchProjects(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "level", required = false) String level,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<ResearchProject> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + search + "%"));
            }
            
            if (status != null && !status.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("projectType"), type));
            }
            
            if (level != null && !level.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("level"), level));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<ResearchProject> projects = researchProjectRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("name", "项目名称");
        headers.put("projectType", "项目类型");
        headers.put("level", "项目级别");
        headers.put("status", "项目状态");
        headers.put("startDate", "开始日期");
        headers.put("endDate", "结束日期");
        headers.put("totalFunding", "资助金额");
        headers.put("user.name", "负责人");
        headers.put("description", "项目描述");
        
        return ExcelExportUtil.exportToExcel(projects, headers, "科研项目列表");
    }

    /**
     * 导出学术成果
     */
    @GetMapping("/academic-achievements")
    public ResponseEntity<byte[]> exportAcademicAchievements(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "status", required = false) String status,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<AcademicAchievement> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.or(
                    criteriaBuilder.like(root.get("title"), "%" + search + "%"),
                    criteriaBuilder.like(root.get("journal"), "%" + search + "%")
                ));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("type"), type));
            }
            
            if (status != null && !status.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("status"), status));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<AcademicAchievement> achievements = academicAchievementRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("title", "成果标题");
        headers.put("type", "成果类型");
        headers.put("journal", "发表期刊/会议");
        headers.put("publishDate", "发表日期");
        headers.put("status", "状态");
        headers.put("impactFactor", "影响因子");
        headers.put("user.name", "作者");
        headers.put("description", "描述");
        
        return ExcelExportUtil.exportToExcel(achievements, headers, "学术成果列表");
    }

    /**
     * 导出获奖情况
     */
    @GetMapping("/awards")
    public ResponseEntity<byte[]> exportAwards(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "level", required = false) String level,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<Award> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("awardName"), "%" + search + "%"));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("category"), type));
            }
            
            if (level != null && !level.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("level"), level));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<Award> awards = awardRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("awardName", "奖项名称");
        headers.put("category", "奖项类型");
        headers.put("level", "奖项级别");
        headers.put("awardingDate", "获奖日期");
        headers.put("awardingOrg", "颁奖机构");
        headers.put("user.name", "获奖人");
        headers.put("description", "描述");
        
        return ExcelExportUtil.exportToExcel(awards, headers, "获奖情况列表");
    }

    /**
     * 导出活动参与
     */
    @GetMapping("/activities")
    public ResponseEntity<byte[]> exportActivities(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<Activity> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("activityName"), "%" + search + "%"));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("activityType"), type));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<Activity> activities = activityRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("activityName", "活动名称");
        headers.put("activityType", "活动类型");
        headers.put("startDate", "活动日期");
        headers.put("location", "活动地点");
        headers.put("participantRole", "参与角色");
        headers.put("user.name", "参与人");
        headers.put("description", "活动描述");
        
        return ExcelExportUtil.exportToExcel(activities, headers, "活动参与列表");
    }

    /**
     * 导出学生指导
     */
    @GetMapping("/student-guidance")
    public ResponseEntity<byte[]> exportStudentGuidance(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<StudentGuidance> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.or(
                    criteriaBuilder.like(root.get("studentName"), "%" + search + "%"),
                    criteriaBuilder.like(root.get("guidanceTopic"), "%" + search + "%")
                ));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("guidanceCategory"), type));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<StudentGuidance> guidances = studentGuidanceRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("studentName", "学生姓名");
        headers.put("guidanceCategory", "指导类型");
        headers.put("guidanceTopic", "项目标题");
        headers.put("startDate", "开始日期");
        headers.put("endDate", "结束日期");
        headers.put("user.name", "指导教师");
        headers.put("description", "指导内容");
        
        return ExcelExportUtil.exportToExcel(guidances, headers, "学生指导列表");
    }

    /**
     * 导出教材编写
     */
    @GetMapping("/textbooks")
    public ResponseEntity<byte[]> exportTextbooks(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<Textbook> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("title"), "%" + search + "%"));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("textbookType"), type));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<Textbook> textbooks = textbookRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("title", "教材名称");
        headers.put("textbookType", "教材类型");
        headers.put("publisher", "出版社");
        headers.put("publishDate", "出版日期");
        headers.put("isbn", "ISBN");
        headers.put("editorRole", "参与角色");
        headers.put("user.name", "作者");
        headers.put("description", "描述");
        
        return ExcelExportUtil.exportToExcel(textbooks, headers, "教材编写列表");
    }

    /**
     * 导出课时统计
     */
    @GetMapping("/course-hours")
    public ResponseEntity<byte[]> exportCourseHours(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "semester", required = false) String semester,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<CourseHours> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("courseName"), "%" + search + "%"));
            }
            
            if (semester != null && !semester.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("academicYear"), semester));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<CourseHours> courseHours = courseHoursRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("courseName", "课程名称");
        headers.put("academicYear", "学期");
        headers.put("theoryHours", "理论课时");
        headers.put("studentCount", "学生人数");
        headers.put("standardHours", "标准课时量");
        headers.put("convertedHours", "折合课时量");
        headers.put("user.name", "授课教师");
        
        return ExcelExportUtil.exportToExcel(courseHours, headers, "课时统计列表");
    }

    /**
     * 导出志愿服务
     */
    @GetMapping("/volunteer-services")
    public ResponseEntity<byte[]> exportVolunteerServices(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<VolunteerService> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("serviceTitle"), "%" + search + "%"));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("serviceType"), type));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<VolunteerService> services = volunteerServiceRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("serviceTitle", "服务名称");
        headers.put("serviceType", "服务类型");
        headers.put("serviceDate", "服务日期");
        headers.put("serviceHours", "服务时长");
        headers.put("location", "服务地点");
        headers.put("user.name", "志愿者");
        headers.put("description", "服务描述");
        
        return ExcelExportUtil.exportToExcel(services, headers, "志愿服务列表");
    }

    /**
     * 导出党建活动
     */
    @GetMapping("/party-activities")
    public ResponseEntity<byte[]> exportPartyActivities(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<PartyActivity> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.like(root.get("activitySubject"), "%" + search + "%"));
            }
            
            if (type != null && !type.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("activityType"), type));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<PartyActivity> activities = partyActivityRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("activitySubject", "活动名称");
        headers.put("activityType", "活动类型");
        headers.put("activityDate", "活动日期");
        headers.put("location", "活动地点");
        headers.put("participantCount", "参与人数");
        headers.put("user.name", "组织者");
        headers.put("description", "活动描述");
        
        return ExcelExportUtil.exportToExcel(activities, headers, "党建活动列表");
    }

    /**
     * 导出学术兼职
     */
    @GetMapping("/academic-positions")
    public ResponseEntity<byte[]> exportAcademicPositions(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "category", required = false) String category,
            @RequestParam(value = "level", required = false) String level,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<AcademicPosition> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.or(
                    criteriaBuilder.like(root.get("positionTitle"), "%" + search + "%"),
                    criteriaBuilder.like(root.get("organizationName"), "%" + search + "%")
                ));
            }
            
            if (category != null && !category.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("positionCategory"), category));
            }
            
            if (level != null && !level.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("level"), level));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<AcademicPosition> positions = academicPositionRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("positionCategory", "职务类别");
        headers.put("positionTitle", "职务名称");
        headers.put("organizationName", "组织机构");
        headers.put("level", "级别");
        headers.put("startDate", "开始日期");
        headers.put("endDate", "结束日期");
        headers.put("user.name", "任职人");
        headers.put("description", "描述");
        
        return ExcelExportUtil.exportToExcel(positions, headers, "学术兼职列表");
    }

    /**
     * 导出人才荣誉
     */
    @GetMapping("/talent-honors")
    public ResponseEntity<byte[]> exportTalentHonors(
            @RequestParam(value = "search", required = false) String search,
            @RequestParam(value = "category", required = false) String category,
            @RequestParam(value = "userId", required = false) Long userId) {
        
        Specification<TalentHonor> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("userId"), userId));
            }
            
            if (search != null && !search.trim().isEmpty()) {
                predicates.add(criteriaBuilder.or(
                    criteriaBuilder.like(root.get("titleFullName"), "%" + search + "%"),
                    criteriaBuilder.like(root.get("grantingOrganization"), "%" + search + "%")
                ));
            }
            
            if (category != null && !category.trim().isEmpty()) {
                predicates.add(criteriaBuilder.equal(root.get("category"), category));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        List<TalentHonor> honors = talentHonorRepository.findAll(spec, Sort.by(Sort.Direction.DESC, "id"));
        
        Map<String, String> headers = new LinkedHashMap<>();
        headers.put("category", "类别");
        headers.put("titleFullName", "荣誉称号");
        headers.put("grantingOrganization", "授予单位");
        headers.put("selectionDate", "入选日期");
        headers.put("validFrom", "有效期起");
        headers.put("validTo", "有效期止");
        headers.put("isPermanent", "是否永久有效");
        headers.put("notes", "备注");
        
        return ExcelExportUtil.exportToExcel(honors, headers, "人才荣誉列表");
    }
}
